﻿using System.ComponentModel;
using System.Data;
using System.Dynamic;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Student.Common
{
    public class ConvertHelper
    {
        public static readonly DateTime DefaultDate = new(1900, 1, 1);

        public static DateTime ToDateTime(string? getDatetime)
        {
            if (getDatetime == "至今" || string.IsNullOrEmpty(getDatetime)) return DefaultDate;
            var result = DateTime.TryParse(getDatetime, out DateTime returnDateTime);
            return result ? returnDateTime : DefaultDate;
        }

        public static DateTime ToDateTime(object getValue)
        {
            if (getValue == null) return DefaultDate;
            return ToDateTime(getValue.ToString());
        }

        /// <summary>
        /// 日期转int，输出格式：yyyyMMdd
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static int DateToInt(DateTime dateTime)
        {
            return ToInt(dateTime.ToString("yyyyMMdd"));
        }

        /// <summary>
        /// int转日期，输入格式：yyyyMMdd
        /// </summary>
        /// <param name="dateValue"></param>
        /// <returns></returns>
        public static DateTime StringToDate(string dateValue)
        {
            return DateTime.ParseExact(dateValue, "yyyyMMdd", CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// 日期转long，输出格式：yyyyMMddHHmmss
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static long DateTimeToLong(DateTime dateTime)
        {
            return ToLong(dateTime.ToString("yyyyMMddHHmmss"));
        }

        /// <summary>
        /// /// <summary>
        /// long转日期，输入格式：yyyyMMddHHmmss
        /// </summary>
        /// <param name="dateTime"></param>
        public static DateTime StringToDateTime(string dateTimeValue)
        {
            return DateTime.ParseExact(dateTimeValue, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// /// <summary>
        /// long转日期，输入格式：yyyyMMddHHmmss
        /// </summary>
        /// <param name="dateTime"></param>
        public static DateTime LongToDateTime(long dateTimeValue)
        {
            return DateTime.ParseExact(dateTimeValue.ToString(), "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
        }

        public static int ToInt(string? getValue)
        {
            var result = int.TryParse(getValue, out int returnValue);
            return result ? returnValue : 0;
        }

        public static int ToInt(object getValue)
        {
            return getValue != null ? ToInt(getValue.ToString()) : 0;
        }

        public static long ToLong(string? getValue)
        {
            var result = long.TryParse(getValue, out long returnValue);
            return result ? returnValue : 0;
        }

        public static long ToLong(object getValue)
        {
            return getValue != null ? ToLong(getValue.ToString()) : 0L;
        }

        public static double ToDouble(string? getValue)
        {
            var result = double.TryParse(getValue, out double returnValue);
            return result ? returnValue : 0.0;
        }

        public static double ToDouble(object getValue)
        {
            if (getValue == null) return 0;
            return ToDouble(getValue.ToString());
        }

        public static decimal ToDecimal(string? getValue)
        {
            var result = decimal.TryParse(getValue, out decimal returnValue);
            return result ? returnValue : 0;
        }

        public static decimal ToDecimal(object getValue)
        {
            if (getValue == null) return 0;
            return ToDecimal(getValue.ToString());
        }

        public static bool ToBool(string? getValue)
        {
            _ = bool.TryParse(getValue, out bool retValue);
            return retValue;
        }

        public static bool ToBool(object getValue)
        {
            if (getValue != null)
            {
                return ToBool(getValue.ToString());
            }
            return false;
        }

        #region 将字典集合转换为动态对象
        /// <summary>
        /// 将字典集合转换为动态对象
        /// </summary>
        /// <param name="propertyDics">属性/属性值字典集合</param>
        /// <returns></returns>
        public static dynamic? DictionaryToDynamic(IDictionary<string, object> propertyDics)
        {
            if (propertyDics == null) return null;

            dynamic result = new ExpandoObject();

            foreach (var entry in propertyDics)
            {
                ((ICollection<KeyValuePair<string, object>>)result).Add(new KeyValuePair<string, object>(entry.Key, entry.Value));
            }

            return result;
        }
        #endregion

        /// <summary>
        /// 四舍五入转整型
        /// </summary>
        /// <param name="getValue"></param>
        /// <returns></returns>
        public static int ToIntRound(decimal getValue)
        {
            return (int)Math.Round(getValue, 0, MidpointRounding.AwayFromZero);
        }

        public static bool IsThisWeek(DateTime someDate)
        {
            DateTime dt = DateTime.Now.Date;

            DateTime nowMon = dt.AddDays(1 - Convert.ToInt32(dt.DayOfWeek.ToString("d")));

            TimeSpan ts = someDate - nowMon;

            if (ts.Days >= 0 && ts.Days < 7)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static int DateToAge(DateTime birthday)//计算周岁
        {
            if (birthday == DefaultDate) return 0;
            DateTime today = DateTime.Today;
            int age = today.Year - birthday.Year;
            if (birthday > today.AddYears(-age)) age--;
            return age;
        }

        public static int StringToInt(string str) //将字符串前端数字转换为数
        {
            var r = Regex.Match(str, @"^\d*").Groups[0].Value;
            if (string.IsNullOrEmpty(r)) return 0;
            return Convert.ToInt32(r);
        }

        public static string StrToInStr(string str)//将形如"A,B,C"转换成"'A','B','C'"字符串
        {
            var result = "";
            string[] strArray = str.Split(',');
            foreach (var s in strArray)
            {
                result += $",'{s}'";
            }
            return result.TrimStart(',');
        }

        public static DataTable ToDataTable<T>(IList<T> data)
        {
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties(typeof(T));
            var table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }

        public static dynamic ToDynamic(object value)
        {
            IDictionary<string, object> expando = new ExpandoObject();

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
                expando.Add(property.Name, property.GetValue(value));

            return expando as ExpandoObject;
        }
    }
}
